﻿using System;
using System.Linq;
using Autodesk.Revit.DB;

namespace YArchitech.Revit
{
	public class LinkedDocument
	{
		public RevitLinkInstance RevitLinkInstance { get; private set; }

		public Document Document
		{
			get
			{
				return this.RevitLinkInstance.GetLinkDocument();
			}
		}

		public BoundingBoxXYZ BoundingBox
		{
			get
			{
				return this.RevitLinkInstance.get_BoundingBox(RevitUtility.CurrentDocument.ActiveView);
			}
		}

		public Transform Transform
		{
			get
			{
				return this.RevitLinkInstance.GetTotalTransform();
			}
		}

		public LinkedDocument(RevitLinkInstance linkInstance)
		{
			this.RevitLinkInstance = linkInstance;
		}

		public XYZ GetPointInDocument(XYZ ptOnInstance)
		{
			return ptOnInstance - this.Transform.Origin;
		}

		public XYZ GetPointInLinkDocument(XYZ ptOnInstance)
		{
			return ptOnInstance + this.Transform.Origin;
		}

		public SelectedElement GetSelectedElement<T>(XYZ pickedPoint, double searchLength = 0.05) where T : Element
		{
			XYZ pointInDocument = this.GetPointInDocument(pickedPoint);
			return new SelectedElement
			{
				SelectedPoint = pointInDocument,
				Element = this.Document.GetElements(pointInDocument, searchLength).FirstOrNull<Element>()
			};
		}

		public SelectedElement GetSelectedElement(XYZ pickedPoint, double searchLength = 0.05)
		{
			XYZ pointInDocument = this.GetPointInDocument(pickedPoint);
			return new SelectedElement
			{
				SelectedPoint = pointInDocument,
				Element = this.Document.GetElements(pointInDocument, searchLength).FirstOrNull<Element>()
			};
		}

		public SelectedElement GetSelectedElementByWallOrColumn(XYZ pickedPoint, double searchLength = 0.05)
		{
			XYZ pointInDocument = this.GetPointInDocument(pickedPoint);
			SelectedElement selectedElement = new SelectedElement();
			selectedElement.SelectedPoint = pointInDocument;
			selectedElement.Element = (from s in this.Document.GetElements(pointInDocument, searchLength)
			where s.GetType() == typeof(FamilyInstance) || s.GetType() == typeof(Wall)
			select s).FirstOrNull<Element>();
			return selectedElement;
		}

		public bool ContainsPoint(XYZ point)
		{
			bool flag = !this.BoundingBox.Min.IsBiggerThan(point);
			bool flag2 = !this.BoundingBox.Max.IsLessThan(point);
			return flag && flag2;
		}

		public bool IsIntersectWithBox(XYZ bottomLeft, XYZ topRight)
		{
			return this.ContainsPoint(bottomLeft) || this.ContainsPoint(topRight);
		}

		public bool IsIntersectWithBox(BoundingBoxXYZ box)
		{
			return this.IsIntersectWithBox(box.Min, box.Max);
		}
	}
}
